﻿/*======================================================================
== Copyright : BlueCurve (c)
== Licence   : Gnu/GPL v2.x
== Author    : Teddy Albina
== Email     : bluecurveteam@gmail.com
== Web site  : http://www.codeplex.com/BlueCurve
========================================================================*/
using System;
using System.Collections.Generic;
using System.Configuration;
using System.ServiceModel;
using System.Threading;
using System.Diagnostics;
using BlueCurve.WcfServices;
using BlueCurve.Common.Application;

namespace QueryServer
{
    class Program : BlueCurve.Common.InteractiveConsole.BaseConsole
    {
        /// <summary>
        /// Instance du cache mémoire
        /// </summary>
        private static QueryServer.Cache<string, string, List<BlueCurve.SearchContract.SearchData>> s_InstanceOfCache = QueryServer.Cache<string, string, List<BlueCurve.SearchContract.SearchData>>.GetInstance;
        /// <summary>
        /// Thread pour la console interactive
        /// </summary>
        private static Thread s_console { get; set; }
        /// <summary>
        /// Thread pour l'écriture dans la base de données
        /// </summary>
        private static Thread s_writer { get; set; }
        /// <summary>
        /// Thread de gestion du cache mémoire
        /// </summary>
        private static Thread s_cache { get; set; }


        static void Main()
        {
            Tcpservice._RestartApplication += new EventHandler(TcpserviceRestartApplication);
            Tcpservice._StopApplication += new EventHandler(TcpserviceStopApplication);

            LuceneIndexWriter.s_UseMultiIndexes = Convert.ToBoolean(ConfigurationManager.AppSettings["UseMultiIndexes"] ?? "false");
            LuceneIndexWriter.Configure(ConfigurationManager.AppSettings["IndexLocation"]);

            s_console = new Thread(new ThreadStart(new Program().Run));
            s_writer = new Thread(new ThreadStart(LuceneIndexWriter.RunIndexation));

            s_console.Start();
            s_writer.Start();

            // Demarrage du service wcf
            Host.StartService<Tcpservice>();
        }



        #region 'Event'

        /// <summary>
        /// Fonction attachée à l'évenement arrêt de l'application
        /// </summary>
        static void TcpserviceStopApplication(object sender, EventArgs e)
        {
            LuceneIndexWriter.IsStop = false;
            while (LuceneIndexWriter.AliveThreads > 0) { Thread.Sleep(100); }

            if (s_writer.ThreadState == System.Threading.ThreadState.Running)
                s_writer.Abort();

            if (s_cache.ThreadState == System.Threading.ThreadState.Running)
                s_cache.Abort();

            // Fermeture du service wcf
            Host.StopService();
            // Suicide de l'application
            Process.GetCurrentProcess().Kill();
        }


        /// <summary>
        /// Fonction attachée à l'évenement redémarrage de l'application
        /// </summary>
        static void TcpserviceRestartApplication(object sender, EventArgs e)
        {
            LuceneIndexWriter.IsStop = false;
            while (LuceneIndexWriter.AliveThreads > 0) { Thread.Sleep(100); }

            if (s_writer.ThreadState == System.Threading.ThreadState.Running)
                s_writer.Abort();

            if (s_cache.ThreadState == System.Threading.ThreadState.Running)
                s_cache.Abort();

            // Enregistre l'application pour le redemarrage
            Restart.RestartApplication(string.Concat(System.Diagnostics.Process.GetCurrentProcess().ProcessName, ".exe"));
            // Fermeture du service wcf
            Host.StopService();
            // Suicide de l'application
            Process.GetCurrentProcess().Kill();

        }

        #endregion





        #region 'Console'

        protected override void LoadCommands()
        {
            this.Commands.Add("-stop", new Dictionary<Action, string>()
            {
                { () => TcpserviceStopApplication("", EventArgs.Empty), "Permet l'arret de l'application" }
            });
            this.Commands.Add("-restart", new Dictionary<Action, string>()
            {
                { () => TcpserviceRestartApplication("", EventArgs.Empty), "Permet de relancer l'application" }
            });
        }

        public override string Name
        {
            get { return "BlueCurve QueryServer "; }
        }

        #endregion
    }
}